#ifdef WITH_OPENGL

#include "render_control_opengl_win32.h"
#include "window_win32.h"
#include "render_control.h"
#include "opengl.h"
#include <iostream>
#include <windows.h>
#include "widget_helper_win32.h"
#include "renderer_opengl.h"

using namespace krryn::system_imp;
using namespace krryn::gui;

void render_control_opengl_impl_win32::make(const krryn::gui::render_control_initializer &a_Initializer){
	GLuint l_PixelFormat = 0;
	widget_hook_win32(this);
	widget_helper_win32::create_window(a_Initializer, m_hWnd, m_hDC);
	m_Fullscreen = a_Initializer.m_Fullscreen;

	static PIXELFORMATDESCRIPTOR l_Pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, 
		PFD_DRAW_TO_WINDOW + PFD_SUPPORT_OPENGL + PFD_DOUBLEBUFFER, 
		PFD_TYPE_RGBA, a_Initializer.m_BitsPerPixel, 0, 0, 0, 0, 0, 0, 
		0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0};

	if(!(l_PixelFormat = ChoosePixelFormat(m_hDC, &l_Pfd))){
		destroy_window();
		throw widget_exception("No matching pixel format descriptor");
	}

	if(!SetPixelFormat(m_hDC, l_PixelFormat, &l_Pfd)){
		destroy_window();
		throw widget_exception("Can't set the pixel format");
	}

	if(!(m_hRC = wglCreateContext(m_hDC))){
		destroy_window();
		throw widget_exception("Can't create rendering context");
		return;
	}

	make_current();

	// Handle vsync setting
	const char *extensions = (const char*)glGetString(GL_EXTENSIONS);

	if(strstr(extensions, "WGL_EXT_swap_control")){
		typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);
		PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;

		wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");

		if(wglSwapIntervalEXT){
			wglSwapIntervalEXT(a_Initializer.m_Vsync);
		}
	}

	m_Renderer = new renderer_opengl();

	std::clog << "Created win32 OpenGL context" << std::endl;
}

void render_control_opengl_impl_win32::destroy_window(){
#if 0
	if(m_Fullscreen){
		ChangeDisplaySettings(NULL, 0);
		ShowCursor(TRUE);
	}

	if(m_hRC){
		wglMakeCurrent(NULL, NULL);
		wglDeleteContext(m_hRC);
		m_hRC = NULL;
	}

	if(m_hDC && !DeleteDC(m_hDC)){
		m_hDC = NULL;
	}

	if(m_hWnd && !DestroyWindow(m_hWnd)){
		m_hWnd = NULL;
	}
#endif
}

void render_control_opengl_impl_win32::make_current(){
	// disable this context if we can't make it current
	if(!wglMakeCurrent(m_hDC, m_hRC)){
		std::cout << "Can't make window current" << std::endl;
		wglMakeCurrent(NULL, NULL);
	}
}

void render_control_opengl_impl_win32::swap_buffers(){
	SwapBuffers(m_hDC);
}

krryn::view::renderer *render_control_opengl_impl_win32::get_renderer(){
	return m_Renderer;
}

#endif